#include "fifo_queue.h"


/* resets the queue fifo */
void fifo_queue_reset(fifo_queue* fifo){
  fifo->head = NULL;
  fifo->tail = NULL;
}

/* puts new at the end of the queue. Returns SUCCESS if success or OUT_OF_MEMORY otherwise */
int32_t fifo_queue_put(fifo_queue* fifo, void* new){
  if(linked_list_add_after_prev(&(fifo->head), fifo->tail, new) == OUT_OF_MEMORY)
    return OUT_OF_MEMORY;
  if(fifo->tail == NULL)
    //the queue was empty
    fifo->tail = fifo->head;
  else
    fifo->tail = (fifo->tail)->next;
  return SUCCESS;
}

/* returns the head of the queue and removes it. Returns NULL if the queue is empty */
void* fifo_queue_get(fifo_queue* fifo){
  if(fifo->head == NULL)
    return NULL;
  void* ret = fifo->head->data;
  if(linked_list_delete_after_prev(&(fifo->head), NULL, fifo->head, NULL) == FAILURE)
    return NULL;
  if(fifo->head == NULL)
    fifo->tail = NULL;
  return ret;
}

/* removes target from the queue fifo. Uses the function compare to know whether the correct element has been found. compare must take two pointers as arguments and returns a boolean result. It also uses the function free_data to know how to free a link's payload. free_data takes one pointer as parameter and returns a boolean result, indicating if the free worked or not. Returns SUCCESS in case of success, FAILURE otherwise. */
int32_t fifo_queue_remove(fifo_queue* fifo, void* target, int32_t (*compare)(void*, void*), int32_t (*free_data)(void*)){
  if(linked_list_delete(&(fifo->head), target, compare, free_data) == FAILURE)
    return FAILURE;
  if(fifo->head == NULL)
    fifo->tail = NULL;
  return SUCCESS;
}


